import SystemApi from '../../../api/flow/SystemApi'
import SqlTool from './SqlTool'
import EventBus from '../libs/EventBus'
import Store from '../store'
import { AppParams } from "@/utils/appParams";

class Utils {
  static IsEmpty (str) {
    if (str === '' || str == null || str === 'undefined') {
      return true
    }
    if (str instanceof Array) {
      return str.length <= 0
    }
    if (str instanceof Object) {
      return Object.keys(str).length === 0
    }
    return false
  }

  /**
   * 格式化时间
   * @param dateTime
   * @param format
   * @returns {string}
   */
  static dateFormatStr (dateTime = new Date(), format = 'yyyy-MM-dd HH:mm:ss') {
    let ret
    const opt = {
      'y+': dateTime.getFullYear().toString(),
      'M+': (dateTime.getMonth() + 1).toString(),
      'd+': dateTime.getDate().toString(),
      'H+': dateTime.getHours().toString(),
      'm+': dateTime.getMinutes().toString(),
      's+': dateTime.getSeconds().toString()
    }
    for (const k in opt) {
      ret = new RegExp('(' + k + ')').exec(format)
      if (ret) {
        format = format.replace(ret[1], (ret[1].length === 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, '0')))
      }
    }
    return format
  }

  // static MessageWarning(mes) {
  //   Vue.prototype.$message({
  //     type: 'warning', message: mes
  //   })
  // }

  // static MessageSuccess(mes) {
  //   Vue.prototype.$message({
  //     type: 'success', message: mes
  //   })
  // }

  /**
   * 防抖 在时间范围内触发一次，重复调用时间会重置
   * @param callback
   * @param waitTime
   * @returns {(function(): void)|*}
   */
  static debounce (callback, delay) {
    let timer
    return function () {
      const context = this
      const args = arguments

      clearTimeout(timer)

      timer = setTimeout(function () {
        callback.apply(context, args)
      }, delay)
    }
  }

  /**
   * 限流 在规定时间内触发一次
   * @param callback
   * @param delay
   * @returns {(function(): void)|*}
   */
  static throttle (callback, delay) {
    let prev = Date.now()
    return function () {
      const context = this
      const args = arguments
      const now = Date.now()
      if (now - prev >= delay) {
        callback.apply(context, args)
        prev = Date.now()
      }
    }
  }

  /**
   * 替换所有字符串
   * @param str
   * @param replace
   * @param standingString
   */
  static replaceAll (str, replace, standingString) {
    if (Utils.IsEmpty(str)) {
      return str
    }
    const _regex = new RegExp(replace, 'g')
    return str.replace(_regex, standingString).split(' ').join('')
  }

  /**
   * 递归出当前节点可以选的入参
   * @param sourceNode
   * @param target
   */
  static traverse (sourceNode, target) {
    sourceNode?.Parents?.forEach((parentNode) => {
      for (const OutParams of parentNode.NodeOutParam.OutParams) {
        if (OutParams.ValueType === 'object') {
          for (const OutObjectParams in OutParams) {
            const op = { nodeId: parentNode.id, ParamName: OutObjectParams }
            this.PUSH(parentNode, op, target)
          }
        } else {
          this.PUSH(parentNode, OutParams, target)
        }
      }
      if (!this.IsEmpty(parentNode.Parents)) {
        this.traverse(parentNode, target)
      }
    })
    return target
  }

  static GetParents (flow) {
    const processors = {}
    for (const p of flow.processors) {
      processors[p.id] = p
    }

    for (const connection of flow.connections) {
      const sourceProcessor = processors[connection.source]
      const targetProcessor = processors[connection.target]

      if (Utils.IsEmpty(sourceProcessor) || Utils.IsEmpty(targetProcessor)) {
        continue
      }

      if (!sourceProcessor.Children) {
        sourceProcessor.Children = []
      }
      sourceProcessor.Children.push(targetProcessor)

      if (!targetProcessor.Parents) {
        targetProcessor.Parents = []
      }
      targetProcessor.Parents.push(sourceProcessor)
    }

    const tree = Object.values(processors).filter(p => !flow.connections.some(c => c.target === p.id))
    flow.treeProcessors = tree
    return flow
  }

  static PUSH (parentNode, OutParams, target) {
    const key = parentNode.id + '_' + OutParams.ParamName
    if (target.findIndex(s => s.key === key) < 0) {
      OutParams.key = key
      OutParams.nodeId = parentNode.id
      OutParams.DataSource = AppParams.DATA_SOURCE_TYPE.NODE
      target.push(OutParams)
    }
  }

  /**
   * 获取节点的输出参数
   *
   * @param Node == null时获取所有节点的输出参数
   * @param ParamType == null时获取所有类型的输出参数
   * @constructor
   */
  static GetNodeOutParams (currentFlow = null, ParamType = null) {
    console.log(currentFlow)
  }

  /**
   * 退出时间
   * Time = null,立即退出
   *
   * @param Time 1000 * 60 * 3 = 180000
   * @constructor
   */
  static Logout (Time = null) {
    if (Time == null) {
      Out()
    }
    setTimeout(() => {
      Out()
    }, Time)

    function Out () {
      sessionStorage.removeItem(AppParams.COMMON.LOGIN_USER_INFO)
      EventBus.$emit(AppParams.JAVA_SCRIPT_EVENT.USER_LOGOUT)
      Store.commit('app/SER_USER_INFO', null)
    }
  }

  /**
   * 设置用户信息
   * @param UserInfo
   * @constructor
   */
  static SetLoginUserInfo (UserInfo) {
    const r = AppParams.COMMON.BUSINESS_USER_ROLE.filter(u => u.tip === UserInfo.role)[0]
    if (r) {
      UserInfo.roleName = r.tip
    }
    Store.commit('app/SER_USER_INFO', UserInfo)
    sessionStorage.setItem(AppParams.COMMON.LOGIN_USER_INFO, JSON.stringify(UserInfo))
    this.Logout(AppParams.COMMON.LOGOUT_TIME)
  }

  /**
   * 获取用户信息
   * @returns {any|null}
   * @constructor
   */
  static GetLoginUserInfo (_TableNames = []) {
    let us = sessionStorage.getItem(AppParams.COMMON.LOGIN_USER_INFO)
    if (this.IsEmpty(us)) {
      return null
    }
    us = JSON.parse(us)
    Store.commit('app/SER_USER_INFO', us)
    if (!Utils.IsEmpty(us.Permissions?.Data) || Utils.IsEmpty(_TableNames)) {
      return us
    }
    const Config = SystemApi.GetSystemConfigInfo()
    // 超级管理员拥有所有权限,
    if (Config?.authentication?.SuperAdmin === 1) {
      let Permissions = []
      for (const tableName of _TableNames) {
        tableName.BUTTONS = SqlTool.TABLES.BUTTONS
        Permissions.push(tableName)
      }
      us.Permissions = Permissions
    }
    return us
  }

  /**
   * 判断是否登录
   * true = 已登录
   * false = 未登录
   * @returns {boolean}
   * @constructor
   */
  static IsAuthentication () {
    return !Utils.IsEmpty(Utils.GetLoginUserInfo())
  }

  /**
   * 缓存用户界面的配置信息
   * @param Type
   * @param ComponentJson
   * @constructor
   */
  static SetUserPageComponentCache (Type, ComponentJson) {
    localStorage.setItem(Type, ComponentJson)
  }

  /**
   * 获取用户界面的配置信息
   *
   * Type === 'Component' ? 'canvasData' : 'canvasStyle'
   * @param Type
   * @returns {string}
   * @constructor
   */
  static GetUserPageComponentCache (Type) {
    return localStorage.getItem(Type)
  }
}

export default Utils
